Contents
  1. 1. Introduction
  2. 2. 总述
  3. 3. 微信开发中的有关坐标
  4. 4. 坐标转化工具
  5. 5. 参考链接
  6. 6. over

Introduction

以前在接触微信定位时就考察过这方面的东西,但是现在看来,当初还是调研不够仔细。

总述

对于坐标系来说,国际上通用的坐标系为WGS-84(World Geodetic System),而国内最基本的也要在此基础上进行一次加密,从而得到一个国内经常使用的坐标系GCJ-02,这种地址也就是常说的火星地址。有些地图厂商为了数据更加安全,有对GCJ-02加密了一次。例如:百度地图进行了BD-09二次加密。下图说明了国内常用地图的坐标系:

微信开发中的有关坐标

微信消息发送的地址采用的是腾讯地图的坐标系;而在开发者模式中,微信服务器推送给开发者的位置事件中的地址是GPS定位的结果,需要转换成百度坐标系(或其他坐标系)才能使用。

这里提供几个在解决问题时遇到的好的工具

坐标转化工具

首先有一个表示地点的类Point

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static class Point {
private BigDecimal longitude;
private BigDecimal latitude;

public static Point getPoint(BigDecimal longitude, BigDecimal latitude) {
return new Point(longitude, latitude);
}

private Point(BigDecimal longitude, BigDecimal latitude) {
this.longitude = longitude;
this.latitude = latitude;
}

public BigDecimal getLongitude() {
return longitude;
}

public BigDecimal getLatitude() {
return latitude;
}
}

百度转GCJ-02

1
2
3
4
5
6
7
8
9
10
public static Point baiduToMars(Point point) {
double x = point.getLongitude().doubleValue() - 0.0065;
double y = point.getLatitude().doubleValue() - 0.006;
double xPi = x / 180.0;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xPi);
BigDecimal longitude = BigDecimal.valueOf(z * Math.cos(theta));
BigDecimal latitude = BigDecimal.valueOf(z * Math.sin(theta));
return Point.getPoint(longitude, latitude);
}

GCJ-02转百度

1
2
3
4
5
6
7
8
9
10
11
12
public static Point marsToBaidu(Point point) {
double xPi = 3.14159265358979324 * 3000.0 / 180.0;
double x = point.getLongitude().doubleValue();
double y = point.getLatitude().doubleValue();
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * xPi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * xPi);
x = z * Math.cos(theta) + 0.0065;
y = z * Math.sin(theta) + 0.006;
BigDecimal longitude = BigDecimal.valueOf(x);
BigDecimal latitude = BigDecimal.valueOf(y);
return Point.getPoint(longitude, latitude);
}

WGS-84转GCJ-02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public static class EvilTransform {//World Geodetic System to Mars Geodetic System
// Krasovsky 1940
static double pi = 3.14159265358979324;
static double a = 6378245.0;
static double ee = 0.00669342162296594323;

public static Point transform(Point point) {
double worldLongitude = point.getLongitude().doubleValue();
double worldLatitude = point.getLatitude().doubleValue();

double dLat = transformLatitude(worldLongitude - 105.0, worldLatitude - 35.0);
double dLon = transformLongitude(worldLongitude - 105.0, worldLatitude - 35.0);
double radLat = worldLatitude / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double marsLatitude = worldLatitude + dLat;
double marsLongitude = worldLongitude + dLon;
return new Point(BigDecimal.valueOf(marsLongitude), BigDecimal.valueOf(marsLatitude));
}

private static double transformLatitude(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}

private static double transformLongitude(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
}

参考链接

Contents
  1. 1. Introduction
  2. 2. 总述
  3. 3. 微信开发中的有关坐标
  4. 4. 坐标转化工具
  5. 5. 参考链接
  6. 6. over